//// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
//package com.linqingying.gitcode.pullrequest.ui
//
//import com.intellij.collaboration.async.cancelledWith
//import com.intellij.collaboration.async.launchNow
//import com.intellij.collaboration.ui.codereview.diff.CodeReviewDiffRequestProducer
//import com.intellij.collaboration.ui.codereview.diff.model.getSelected
//import com.intellij.collaboration.util.ChangesSelection
//import com.intellij.collaboration.util.getOrNull
//import com.intellij.openapi.Disposable
//import com.intellij.openapi.project.Project
//import com.intellij.platform.util.coroutines.childScope
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.ExperimentalCoroutinesApi
//import kotlinx.coroutines.flow.*
//import com.linqingying.gitcode.pullrequest.config.GitCodePullRequestsProjectUISettings
//import com.linqingying.gitcode.pullrequest.data.GCPRDataContext
//import com.linqingying.gitcode.pullrequest.data.GCPRIdentifier
//import com.linqingying.gitcode.pullrequest.data.provider.GCPRDataProvider
//import com.linqingying.gitcode.pullrequest.ui.comment.GCPRThreadsViewModels
//import com.linqingying.gitcode.pullrequest.ui.diff.GCPRDiffViewModel
//import com.linqingying.gitcode.pullrequest.ui.diff.GCPRDiffViewModelImpl
//import com.linqingying.gitcode.pullrequest.ui.editor.GCPRReviewInEditorViewModel
//import com.linqingying.gitcode.pullrequest.ui.editor.GCPRReviewInEditorViewModelImpl
//import com.linqingying.gitcode.pullrequest.ui.review.GCPRBranchWidgetViewModel
//import com.linqingying.gitcode.pullrequest.ui.review.GCPRBranchWidgetViewModelImpl
//import com.linqingying.gitcode.pullrequest.ui.review.GCPRReviewViewModelHelper
//import com.linqingying.gitcode.pullrequest.ui.timeline.GCPRTimelineViewModel
//import com.linqingying.gitcode.pullrequest.ui.timeline.GCPRTimelineViewModelImpl
//import com.linqingying.gitcode.pullrequest.ui.toolwindow.model.GCPRInfoViewModel
//import com.linqingying.gitcode.pullrequest.ui.toolwindow.model.GCPRToolWindowProjectViewModel
//
//@OptIn(ExperimentalCoroutinesApi::class)
//internal class GCPRViewModelContainer(
//  project: Project,
//  parentCs: CoroutineScope,
//  dataContext: GCPRDataContext,
//  private val projectVm: GCPRToolWindowProjectViewModel,
//  private val pullRequestId: GCPRIdentifier,
//  cancelWith: Disposable
//) {
//  private val cs = parentCs.childScope().cancelledWith(cancelWith)
//
//  private val dataProvider: GCPRDataProvider = dataContext.dataProviderRepository.getDataProvider(pullRequestId, cancelWith)
//
//  private val diffSelectionRequests = MutableSharedFlow<ChangesSelection>(1)
//
//  private val lazyInfoVm = lazy {
//    GCPRInfoViewModel(project, cs, dataContext, dataProvider).apply {
//      setup()
//    }
//  }
//  val infoVm: GCPRInfoViewModel by lazyInfoVm
//  private val reviewVmHelper: GCPRReviewViewModelHelper by lazy { GCPRReviewViewModelHelper(cs, dataProvider) }
//
//  private val branchStateVm by lazy {
//    GCPRReviewBranchStateSharedViewModel(cs, dataContext, dataProvider)
//  }
//  private val settings = GitCodePullRequestsProjectUISettings.getInstance(project)
//  val branchWidgetVm: GCPRBranchWidgetViewModel by lazy {
//    GCPRBranchWidgetViewModelImpl(cs, settings, dataProvider, projectVm, branchStateVm, reviewVmHelper, pullRequestId)
//  }
//
//  private val threadsVms = GCPRThreadsViewModels(project, cs, dataContext, dataProvider)
//  val diffVm: GCPRDiffViewModel by lazy {
//    GCPRDiffViewModelImpl(project, cs, dataContext, dataProvider, reviewVmHelper, threadsVms).apply {
//      setup()
//    }
//  }
//
//  val editorVm: GCPRReviewInEditorViewModel by lazy {
//    GCPRReviewInEditorViewModelImpl(project, cs, settings, dataContext, dataProvider, branchStateVm, threadsVms) {
//      diffSelectionRequests.tryEmit(it)
//      projectVm.openPullRequestDiff(pullRequestId, true)
//    }
//  }
//
//  val timelineVm: GCPRTimelineViewModel by lazy {
//    GCPRTimelineViewModelImpl(project, cs, dataContext, dataProvider).apply {
//      setup()
//    }
//  }
//
//  init {
//    cs.launchNow {
//      dataProvider.stateData.stateChangeSignal.collectLatest {
//        projectVm.refreshPrOnCurrentBranch()
//      }
//    }
//  }
//
//  private fun GCPRInfoViewModel.setup() {
//    cs.launchNow {
//      detailsVm.flatMapLatest { detailsVmResult ->
//        detailsVmResult.getOrNull()?.changesVm?.changeListVm?.flatMapLatest {
//          it.getOrNull()?.changesSelection ?: flowOf(null)
//        } ?: flowOf(null)
//      }.filterNotNull().collect(diffSelectionRequests)
//    }
//  }
//
//  private fun GCPRDiffViewModelImpl.setup() {
//    cs.launchNow {
//      diffSelectionRequests.collect {
//        showDiffFor(it)
//      }
//    }
//
//    cs.launchNow {
//      diffVm.flatMapLatest {
//        it.result?.getOrNull()?.producers?.map { state -> (state.getSelected() as? CodeReviewDiffRequestProducer)?.change } ?: flowOf(null)
//      }.collectLatest {
//        if (lazyInfoVm.isInitialized() && it != null) {
//          lazyInfoVm.value.detailsVm.value.getOrNull()?.changesVm?.selectChange(it)
//        }
//      }
//    }
//  }
//
//  private fun GCPRTimelineViewModelImpl.setup() {
//    cs.launchNow {
//      showCommitRequests.collect {
//        projectVm.viewPullRequest(pullRequestId, it)
//      }
//    }
//
//    cs.launchNow {
//      showDiffRequests.collect {
//        diffVm.showDiffFor(it)
//        projectVm.openPullRequestDiff(pullRequestId, true)
//      }
//    }
//  }
//}
